#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2018, Niklas Hauser
#
# This file is part of the modm project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# -----------------------------------------------------------------------------

import itertools, math

def init(module):
    module.name = ":ui:led"
    module.description = FileReader("module.md")

def prepare(module, options):

    module.add_set_option(
        NumericOption(
            name="gamma",
            description="Gamma correction of values",
            minimum=1.0,
            maximum=3.0),
        default=2.2)
    module.add_set_option(
        NumericOption(
            name="bit",
            description="Resolution of target values",
            minimum=2,
            maximum=16),
        default=[7, 8, 12, 16])
    module.add_set_option(
        NumericOption(
            name="range",
            description="Range of input values",
            minimum=2,
            maximum=1024),
        default=256)

    module.depends(
        ":architecture:accessor",
        ":architecture:clock",
        ":processing:timer",
        ":ui:animation",
        ":ui:color")
    return True

tables = []

def validate(env):
    option_table = itertools.product(
        sorted(env[":::gamma"]), sorted(env[":::bit"]), sorted(env[":::range"]))

    for gamma, bit, length in option_table:
        env.log.info("Generating led table with gamma: {}, bit: {}, range: {}".format(gamma, bit, length))
        # specifies how many values are written per line
        values_per_line = 16

        # check which type width is needed
        size = 1 if bit <= 8 else 2
        ttype = "uint{}_t".format(size * 8)
        size *= length

        values = []
        bmax = 2 ** bit - 1

        for index in range(length):
            # generate the value for the index
            value = int(( bmax / ((length - 1) ** gamma)) * (index ** gamma))

            # 0 only on index 0, otherwise at least 1
            if index != 0 and value == 0:
                value = 1
            # Force last value to be max value
            if index == length-1:
                value = bmax

            values.append(value)

        global tables
        tables.append({
            "gamma": int(10 * gamma),
            "type": ttype,
            "bit": bit,
            "bit_range": 2 ** bit,
            "size": size,
            "range": length,

            "table": values,
            "line": values_per_line,
        })

def build(env):
    env.outbasepath = "modm/src/modm/ui/led"
    env.copy("led.hpp")
    env.copy("rgb.hpp")
    env.copy("../led.hpp")

    global tables
    env.substitutions = {"tables": tables}
    env.template("tables.hpp.in")

    env.outbasepath = "modm/src/modm/ui/led/tables"
    for table in tables:
        env.substitutions = table
        env.template("table.cpp.in", "table{gamma}_{bit}_{range}.cpp".format(**table))




